package com.taobao.snowsnow.web.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.dom4j.DocumentException;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.taobao.api.ApiException;
import com.taobao.snowsnow.hibernate.pojo.Orders;
import com.taobao.snowsnow.hibernate.pojo.Trade;
import com.taobao.snowsnow.hibernate.service.BuyyerService;
import com.taobao.snowsnow.hibernate.service.CategoryService;
import com.taobao.snowsnow.hibernate.service.ColorService;
import com.taobao.snowsnow.hibernate.service.DimensionService;
import com.taobao.snowsnow.hibernate.service.ProductCollectService;
import com.taobao.snowsnow.hibernate.service.TradeService;
import com.taobao.snowsnow.hibernate.service.TypeService;
import com.taobao.snowsnow.taobao.TradeSync;
import com.taobao.snowsnow.util.SpringServiceInit;
import com.taobao.snowsnow.util.Util;

public class GetTrade extends HttpServlet {

	private static final long serialVersionUID = -5635767146268928869L;
	
	private ApplicationContext context;
	
	private TradeService tradeService;
	private ProductCollectService productCollectService;
	private ColorService colorService;
	private DimensionService dimensionService;
	private CategoryService categoryService;
	private TypeService typeService;
	private BuyyerService buyyerService;
	
	private SpringServiceInit springServer = new SpringServiceInit();
	
	private TradeSync sync;
	private Map<String, String> map = new HashMap<String, String>();
	
	private final static int SYNC_DAY = 5;

	public GetTrade() {
		super();
	}

	/**
	 * Destruction of the servlet. <br>
	 */
	public void destroy() {
		super.destroy(); // Just puts "destroy" string in log
		// Put your code here
	}

	/**
	 * The doGet method of the servlet. <br>
	 *
	 * This method is called when a form has its tag value method equals to get.
	 * 
	 * @param request the request send by the client to the server
	 * @param response the response send by the server to the client
	 * @throws ServletException if an error occurred
	 * @throws IOException if an error occurred
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html");
//		response.setContentType("text/xml");
		response.setCharacterEncoding("utf8");
		
		try {
			List<Trade> tradeList = null;
			
		 	// TODO 因为发货程序没有完善,所以要同步多天以前的订单状态,所以这里暂时不能用SYNC_INCREMENT_MODE模式来同步
		 	// 因为发货程序没有写完,所以这里要同步淘宝的订单状态,这里是防止1天前的订单状态变更,然后,以后状态又同步不了
			// 设置订单查询时间
			// 只能查询5天的订单
			Calendar now = Calendar.getInstance();
			Date end = now.getTime();
			
			now.set(Calendar.DAY_OF_MONTH, now.get(Calendar.DAY_OF_MONTH) - SYNC_DAY);
			Date start = now.getTime();
			sync = new TradeSync(TradeSync.SYNC_NORMAL_MODE, null, start, end);
			
			System.out.println(sync.getUpdateTradeNum());
			
			String buyyer = request.getParameter("buyyer");
			if(buyyer != null) {
				tradeList = tradeService.findByTaoBaoID(buyyer);
			} else {
				tradeList = tradeService.findByCriteria(setExpression(request));
			}
			
			// 订单按时间排序, 现在是最早的订单排在最后
			sortTradeByCreateTime(tradeList);
			
			// 为了避免Session close, 因为Action转发Session后, session 就不能打开, 所以 只能在这里加载要关联的属性
			for(Trade trade : tradeList) {
				trade.getPeople().getTaobaoId();

				for(Orders o : trade.getOrders()) {
					o.getProduct().getProductCollect().getName();
				}
			}
			
			request.getSession(true).setAttribute("tradeList", tradeList);
			request.getSession(true).setAttribute("test", "test");
			response.sendRedirect("trade.jsp");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private List<Criterion> setExpression(HttpServletRequest request) throws ParseException {
		List<Criterion> expression = new ArrayList<Criterion>();
		
		String status = request.getParameter("status");
		String create = request.getParameter("create");
		String pay = request.getParameter("pay");
		String start_date = request.getParameter("start_date");
		String end_date = request.getParameter("end_date");
		String price = request.getParameter("price");
		String tid = request.getParameter("tid");
		
		if(tid != null) {
			String tid_oppr = request.getParameter("tid_oppr");
			expression.add(getExpression( "tid", tid, "long", tid_oppr));
		}
		
		if(status != null) {
			String status_oppr = request.getParameter("status_oppr");
			expression.add(getExpression("status", status, "int", status_oppr));
		}
		
		if(create != null) {
			String create_oppr = request.getParameter("create_oppr");
			try {
				expression.add(getExpression("create", create, null, create_oppr, start_date, end_date));
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		
		if(pay != null) {
			String pay_oppr = request.getParameter("pay_oppr");
			try {
				expression.add(getExpression("pay", pay, null, pay_oppr, start_date, end_date));
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		
		if(price != null) {
			String price_oppr = request.getParameter("price_oppr");
			expression.add(getExpression("price", price, "float", price_oppr));
		}
		
		return expression;
	}
	
	private Criterion getExpression(String propertyName, Object property, String propertyType, String oppr, String start_date, String end_date) throws ParseException {
		
		if(property.equals("create") ||  property.equals("pay")) {
			if(end_date != null) {
				return Restrictions.between(map.get(propertyName), getFormateDate(start_date), getFormateDate(end_date));
			} else {
				if(oppr.equals("gt"))
					return (Restrictions.gt(map.get(propertyName), getFormateDate(start_date)));
				else if(oppr.equals("lt"))
					return (Restrictions.gt(map.get(propertyName), getFormateDate(start_date)));
				else if(oppr.equals("le"))
					return (Restrictions.le(map.get(propertyName), getFormateDate(start_date)));
				else if(oppr.equals("ge"))
					return (Restrictions.ge(map.get(propertyName), getFormateDate(start_date)));
			}
		} else {
			if(oppr.equals("gt")) {
				return (Restrictions.gt(map.get(propertyName), property));
			} else if(oppr.equals("ge")) {
				return (Restrictions.ge(map.get(propertyName), property));
			} else if(oppr.equals("eq")) {
				return (Restrictions.eq(map.get(propertyName), property));
			} else if(oppr.equals("lt")) {
				return (Restrictions.lt(map.get(propertyName), property));
			} else if(oppr.equals("le")) {
				return (Restrictions.le(map.get(propertyName), property));
			}
		}
		
		return null;				
	}
	
	private Date getFormateDate(String date_str) throws ParseException {
		return new SimpleDateFormat(Util.DATE_FORMAT_STR).parse(date_str);
	}
	
	private Criterion getExpression(String propertyName, String property, String propertyType, String oppr) throws ParseException {
		Object o = null;
		
		if(propertyType.equals("int"))
			o = new Integer(property);
		
		if(propertyType.equals("long"))
			o = new Long(property);
		
		if(propertyType.equals("float"))
			o = new Float(property);
		
		if(propertyType.equals("string"))
			o = new String(property);
		
		return getExpression(propertyName, o, propertyType, oppr, null, null);			
	}

	/**
	 * 冒泡法排序订单
	 * @param list
	 */
	public void sortTradeByCreateTime(List<Trade> list) {
		for(int i = 1; i < list.size(); i++) {
			 for(int j =0; j < list.size() - i; j++) {
				 long newTime, olderTime;
				 
				 olderTime = list.get(j).getCreateTime().getTime();
				 newTime = list.get(j + 1).getCreateTime().getTime();
				 
				 if(olderTime < newTime) {
					 Trade temp;
					 temp = list.get(j);
					 list.set(j, list.get(j + 1));
					 list.set(j + 1, temp);
				 }
			 }
		 }
	}
	
	/**
	 * The doPost method of the servlet. <br>
	 *
	 * This method is called when a form has its tag value method equals to post.
	 * 
	 * @param request the request send by the client to the server
	 * @param response the response send by the server to the client
	 * @throws ServletException if an error occurred
	 * @throws IOException if an error occurred
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
		out.println("<HTML>");
		out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
		out.println("  <BODY>");
		out.print("    This is ");
		out.print(this.getClass());
		out.println(", using the POST method");
		out.println("  </BODY>");
		out.println("</HTML>");
		out.flush();
		out.close();
	}

	/**
	 * Initialization of the servlet. <br>
	 *
	 * @throws ServletException if an error occurs
	 */
	public void init() throws ServletException {
		context = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
		
		productCollectService = (ProductCollectService) context.getBean("ProductCollectService");
		colorService = (ColorService) context.getBean("ColorService");
		dimensionService = (DimensionService) context.getBean("DimensionService");
		categoryService = (CategoryService) context.getBean("CategoryService");
		typeService = (TypeService) context.getBean("TypeService");
		buyyerService = (BuyyerService) context.getBean("BuyyerService");
		tradeService = (TradeService) context.getBean("TradeService");
		
		springServer.setBuyyerService(buyyerService);
		springServer.setTypeService(typeService);
		springServer.setTradeService(tradeService);
		springServer.setCategoryService(categoryService);
		springServer.setDimensionService(dimensionService);
		springServer.setColorService(colorService);
		springServer.setProductCollectService(productCollectService);
		
		map.put("status", "status");
		map.put("create", "createTime");
		map.put("pay", "payTime");
		map.put("buyyer", "people");
		map.put("price", "totalPrice");
		map.put("tid", "tid");
	}

}
